// filename ******** main.c ************** 
// EE319K Lab 7 starter system    
//    Jonathan W. Valvano  3/29/11
// Potentiometer connected to 9S12

#include <hidef.h>        /* common defines and macros */
#include "derivative.h"   /* derivative-specific definitions */
#define CALLENGTH 10  // number of calibration points

unsigned short Data;      // 10-bit ADC
unsigned short Position;  // 16-bit fixed-point 0.01 cm

void PLL_Init(void);
void ADC_Init(void);
void SCI1_Init(void);
void SCI1_InData(unsigned short* d);
unsigned short ADC_In2(void);
void LCD_Open(void);
void LCD_GoTo(unsigned short position);
void LCD_Clear(void);
void LCD_OutDec(unsigned short number);
void LCD_OutString(char *pt);
void LCD_OutFix(unsigned short integerPart);
void Timer_Wait10ms(unsigned short time);
void Timer_Init(void);
void OC0_Init(void);
unsigned short Convert(unsigned short data);
extern unsigned char ADCStatus;
extern unsigned short ADCMail;

unsigned short adcVals[] = 
{
  0,
  91,
  308,
  487,
  602,
  711,
  840,
  898,
  1005,
  1023
};

unsigned short lenVals[] = 
{
  10,    //70
  30,    //160
  70,    //323
  100,   //480
  120,   //578
  140,   //685
  160,   //770
  170,   //827
  190,   //920
  210    //977
};

//*********  Convert *********
// converts 10-bit ADC to fixed-point position in cm
// Input: 10-bit ADC 0 to 1023
// Output: position in 0.01 cm
// needs calibration
unsigned short Convert(unsigned short data)
{
	unsigned short position;
	// write this function
  
	unsigned short i;
  
	if(data < adcVals[0])
	{
		position = data*lenVals[0]/adcVals[0];
	}
	else if(data >= adcVals[CALLENGTH-1])
	{
		//return ((lenVals[CALLENGTH-1]-lenVals[CALLENGTH-2])/(adcVals[CALLENGTH-1]-adcVals[CALLENGTH-2])*
		int slopeTop = lenVals[CALLENGTH-1]-lenVals[CALLENGTH-2];
		int slopeBottom = adcVals[CALLENGTH-1]-adcVals[CALLENGTH-2];
		int pointX = adcVals[CALLENGTH-2];
		int pointY = lenVals[CALLENGTH-2];

		position = slopeTop*(data-pointX)/slopeBottom+pointY;
	}
	else
	{
		for(i=0;i<CALLENGTH-1;i++)
		{
			if(data >= adcVals[i] && data <= adcVals[i+1])
			{
				//printf("i: %d, slopes[i+1]: %d, data: %d, adcVals[i]: %d, lenVals[i]: %d\n", i, slopes[i+1], data, adcVals[i], lenVals[i]);
				int slopeTop = lenVals[i+1]-lenVals[i];
				int slopeBottom = adcVals[i+1]-adcVals[i];
				int pointX = adcVals[i];
				int pointY = lenVals[i];

				position = slopeTop*(data-pointX)/slopeBottom+pointY;
				
				break;
			}
		}
	}
	return position;
}

void main(void){
  DDRH = 0xFF;
  PTH = 0xFF;
  PLL_Init();  // E clock is 24 MHz in both RUN and LOAD modes
  Timer_Init();
  LCD_Open();
  SCI1_Init();
  //OC0_Init();
  //ADC_Init();
  LCD_Clear();
  LCD_OutString("EE319K");
asm cli        // enable debugger
  for(;;)
  {
    SCI1_InData(&Data);
    LCD_Clear();
    Position = Convert(Data);  // you write this function
    LCD_OutFix(Position);
    LCD_OutString(" cm");
    //Timer_Wait10ms(10); // 100ms wait
  }
}
